﻿/**
* ...
* @author Default
* @version 0.1
*/

package kizzo.utils 
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.errors.*;
	
	import kizzo.utils.*;
	

	public class CommandQueue extends EventDispatcher
	{				
		private var command_array:Array;
		private var command_pointer:Number;
		
		private var status:String;
		
		private var timeout:int = 10000;
		
		public static const COMPLETE:String = "COMPLETE";
		public static const FAIL:String = "FAIL";
		
		function CommandQueue()
		{	
			this.command_array = [];
			this.status = "stopped";
		}
		
		public function add(command:Command):void
		{			
			this.command_array.push(command);
		}
		
		public function execute():void
		{			
			if (this.status == "stopped")
			{
				this.status = "running";
				this.command_pointer = 0;
				//if (this.command_array.length == 0)
				//	throw new Error("Trying to execute CommandQueue of zero length");
				//else
				execute_command();
			}
			else
				throw new Error("Trying to start a CommandQueue that is already running");
		}
		
		private function execute_command():void
		{			
			if (this.command_array[this.command_pointer] != null)
				{
					this.command_array[this.command_pointer].execute();					
					if (this.command_array[this.command_pointer].type == Command.SYNC)
					{		
						this.command_pointer ++;
						execute_command();
					}
					else
					{						
						var event:Event = this.command_array[this.command_pointer].event;						
						var broadcaster:EventDispatcher = this.command_array[this.command_pointer].broadcaster;						
						broadcaster.addEventListener(event.type, continue_execution);	
					}					
				}
			else
				{					
					this.status = "stopped";					
					dispatchEvent(new CustomEvent(COMPLETE, {}));					
				}
		}
		
		private function continue_execution(event:Event):void
		{			
			var complete_event:Event;
			if (event is CustomEvent)
			{				
				var custom_event:CustomEvent = event as CustomEvent;
				if (custom_event.compare(this.command_array[this.command_pointer].event))
				{										
					var broadcaster:Object = this.command_array[this.command_pointer].broadcaster;
					complete_event = this.command_array[this.command_pointer].event;
					broadcaster.removeEventListener(complete_event.type, continue_execution);
					this.command_pointer ++;
					execute_command();			
				}
			}			
			else if (event is Event)
			{
				broadcaster = this.command_array[this.command_pointer].broadcaster;
				complete_event = this.command_array[this.command_pointer].event;
				broadcaster.removeEventListener(complete_event.type, continue_execution);				
				this.command_pointer ++;
				execute_command();		
			}
			else
			{
				throw new Error("Unknown event type while processing command queue.");
			}
		}
		
	}
	
}
